package com.alibaba.otter.node.etl.load.loader.mq.rabbit.namespace;

import com.alibaba.otter.node.etl.load.loader.mq.rabbit.exception.NamespaceException;
import com.alibaba.otter.node.etl.load.loader.mq.rabbit.model.RabbitMqNamespace;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.core.env.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@SuppressWarnings({"unchecked", "rawtypes"})
public class NamespaceManager {

    //   private static MutablePropertySources sources = new MutablePropertySources();
    private static Map<String, Map<String, Object>> sourceMap = new HashMap<>();
//    public static void appendConfig(StandardEnvironment environment) {
//        MutablePropertySources tmpSources = environment.getPropertySources();
//        for (PropertySource<?> tmpSource : tmpSources) {
////            if (tmpSource instanceof CompositePropertySource) {
////                log.info("Using config center, extracting PropertySource");
////                CompositePropertySource source = (CompositePropertySource) tmpSource;
////
////                source.getSource()
////                source.getPropertySources().forEach(propertySource -> sources.addLast(propertySource));
////            } else {
////
////            }
//            sources.addLast(tmpSource);
//        }
//    }

    public static void appendConfig(String namespace, Map<String, Object> map) {
        //   sources.addLast(new MapPropertySource(UUID.randomUUID().toString(), map));

        sourceMap.put(namespace, map);
    }

//    public static void appendConfig(Properties properties) {
//        sources.addLast(new PropertiesPropertySource(UUID.randomUUID().toString(), properties));
//    }

    private static LoadingCache<NamespaceResolver, Namespace> namespaceCache = CacheBuilder.newBuilder()
            .build(new CacheLoader<NamespaceResolver, Namespace>() {
                @Override
                public Namespace load(NamespaceResolver resolver) {
//                    Map<String, Object> targetProperties = new HashMap<>();
//                    sources.iterator().forEachRemaining(next -> {
//                        Object source = next.getSource();
//                        if (source instanceof Map) {
//                            Map<String, Object> tmpMap = (Map) source;
//                            tmpMap.entrySet().stream()
//                                    .filter(entry -> entry.getKey().startsWith(resolver.getPrefix()))
//                                    .forEach(entry -> targetProperties.put(entry.getKey(), entry.getValue()));
//                        } else {
//                            log.info("unknown property source: " + source.getClass());
//                        }
//                    });
//                    if (MapUtils.isEmpty(targetProperties)) {
//                        throw new NamespaceException("no config found for namespace: " + resolver.getName());
//                    }
                    // return resolver.resolve(targetProperties);

                    return resolver.resolve(sourceMap.get(resolver.getName()));
                }
            });

    public static Namespace get(NamespaceResolver resolver) {
        try {
            return namespaceCache.get(resolver);
        } catch (ExecutionException e) {
            log.error("读取namespace属性出错，请检查配置", e);
            throw new NamespaceException("读取namespace属性出错，请检查配置");
        }
    }
}
